/*
 * Copyright (c) 2010-2011 Josef Hardi <josef.hardi@gmail.com>
 * Copyright (c) 2010 Piotr Zagawa <piotr.zagawa@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package id.duapuluhdua.dakidaki.common;

import java.util.Observable;
import java.util.Observer;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Spinner;

import id.duapuluhdua.dakidaki.MainState;
import id.duapuluhdua.dakidaki.Preferences;
import id.duapuluhdua.dakidaki.R;
import id.duapuluhdua.dakidaki.Request;
import id.duapuluhdua.dakidaki.StateBundle;
import id.duapuluhdua.dakidaki.TileMapManager;
import id.duapuluhdua.dakidaki.UserAction;
import id.duapuluhdua.dakidaki.activities.ActivityMain;
import id.duapuluhdua.dakidaki.data.common.DataTable;
import id.duapuluhdua.dakidaki.data.common.DataTableOperation;
import id.duapuluhdua.dakidaki.data.common.DataValues;
import id.duapuluhdua.dakidaki.data.common.Database;
import id.duapuluhdua.dakidaki.data.tables.DataTableTracks;
import id.duapuluhdua.dakidaki.service.ServiceCommand;

/**
 *
 */
public abstract class CommonActivity extends Activity
    implements CommonActivityTable.DataControlsTransfer, Observer
{
  /** Constants */
  public final static int REQUEST_CODE_DEFAULT = 0;
  public final static String ACTIVITIES_PACKAGE = ".activities.";

  /** Fields */
  protected Context mContext;
  protected String sAppTitle;

  protected Preferences mPreference;
  protected Database mDatabase;
  protected UserAction mAction;
  protected TileMapManager mTileManager;

  protected MainState mState;
  protected Request mInitialRequest; // start command data for this activity
  protected StateBundle mSavedState;
  protected CommonActivityTable mActivityTable;

  @Override
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);

    // Common reference
    mContext = this;

    // Initialize main objects
    mDatabase = new Database(this, true);
    mState = new MainState(this, mDatabase);
    mAction = new UserAction(this);
    mPreference = new Preferences(this);
    mTileManager = new TileMapManager(this);

    // Command data
    mInitialRequest = getCommandDataFromIntent();

    // Activity state
    mSavedState = new StateBundle(savedInstanceState);

    // common helpers
    mActivityTable = new CommonActivityTable(this);

    // main title
    sAppTitle = getResString(R.string.app_name);
  }

  @Override
  protected void onStart()
  {
    // Load updated settings
    mPreference.load();

    // initialize global types
//    DataItem.init(database);

    // Watch for state change in loader collection
//    database.getTableTracks().updateObserver(ActivityMain.loader.getTracks());

    // Watch for state change in this activity
//    database.getTableTracks().updateObserver(this);

    // update current main state
    mState.update();

    // get data to view/edit
//    if (cmdStartData.isViewMode() || cmdStartData.isEditMode()) {
//      activityTable.getDataForView();
//    }

    super.onStart();
  }

  @Override
  protected void onDestroy()
  {
//    database.close();

    super.onDestroy();
  }

  public String getApplicationName()
  {
    return sAppTitle;
  }

  public UserAction getUserAction()
  {
    return mAction;
  }

  /**
   * Retrive the main state object.
   *
   * @return
   */
  public MainState getMainState()
  {
    return mState;
  }

  public Database getDatabase()
  {
    return mDatabase;
  }

  public Preferences getPrefs()
  {
    return mPreference;
  }

  public TileMapManager getTileManager()
  {
    return mTileManager;
  }

  public String getResString(int resId)
  {
    return mContext.getResources().getString(resId);
  }

  /**
   * Override to reading values from controls for update.
   */
  @Override
  public DataValues getControlValuesForUpdate(DataTable table)
  {
    return null;
  }

  public void setData(DataTable table)
  {
    mActivityTable.setData(table, mInitialRequest);
    mSavedState.setDataTable(table);
  }

  /**
   * Override to set controls values from current row for view/edit.
   */
  @Override
  public void setControlValuesForView(DataValues values)
  {
    // Do nothing!
  }

  /**
   * Override for observer.
   */
  @Override
  public void update(Observable observable, Object data)
  {
    DataTableOperation op = null;
    if (data instanceof DataTableOperation)
      op = (DataTableOperation) data;

    // Watch for tracks data table changes
    if (observable instanceof DataTableTracks) {
      if (op != null) {
        // Update track
        if (op.operation == DataTableOperation.OP_UPDATE) {
          mState.update();  // reload state

          // Update service state
          ServiceCommand.send(op.command, op.rowId, op.trackName);
        }
        // Insert track
        if (op.operation == DataTableOperation.OP_INSERT) {
          mState.update();  // reload state
        }
        // Delete track
        if (op.operation == DataTableOperation.OP_DELETE) {
          mState.update();  // reload state
        }

        // Send event to main
        if (!(this instanceof ActivityMain))
          ActivityMain.onChangeTableState(op, DataTableTracks.tableName);
      }
    }
  }

  public void setSubTitle(int resId)
  {
    setSubTitle(getResString(resId));
  }

  public void setSubTitle(String subTitle)
  {
    if (subTitle == null) {
      this.setTitle(sAppTitle);
    }
    if (subTitle.length() == 0) {
      this.setTitle(sAppTitle);
    }
    this.setTitle(sAppTitle + " - " + subTitle);
  }

  private Request getCommandDataFromIntent()
  {
    Intent it = getIntent();
    if (it != null) {
      Bundle data = it.getExtras();
      if (data != null) {
        return new Request(data);
      }
    }
    return new Request(Request.MODE_NONE);
  }

  /**
   *
   * @param classToShow
   * @param requestCode
   * @param data
   */
  public void showActivity(Class<?> classToShow, int requestCode, Request data)
  {
    final String sPackage = getPackageName();

    Intent it = new Intent(Intent.ACTION_DEFAULT);

    it.setClassName(this, sPackage + ACTIVITIES_PACKAGE + classToShow.getSimpleName());

    if (data != null) {
      it.putExtras(data.getBundle());
    }

    this.startActivityForResult(it, requestCode);
  }

  /**
   *
   * @param classToShow
   * @param data
   */
  public void showActivity(Class<?> classToShow, Request data)
  {
    showActivity(classToShow, REQUEST_CODE_DEFAULT, data);
  }

  /**
   *
   * @param classToShow
   */
  public void showActivity(Class<?> classToShow)
  {
    showActivity(classToShow, REQUEST_CODE_DEFAULT, null);
  }

  /**
   *
   * @param spinner
   * @param vecItem
   */
  public void setItemsForSpinner(Spinner spinner, String[] vecItem)
  {
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(
        this, android.R.layout.simple_spinner_item, vecItem);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);
  }
}
